import React, { FC, useState, useEffect, useRef, useCallback } from 'react';
import { HistoryTask, UserTask, TaskItem } from './interface';
import { Steps, Accordion, Toast } from 'antd-mobile-v2';
import { connect } from 'react-redux';
import { ConnectState, ConnectProps } from 'typings/connect';
import styles from './index.module.less';
import { getProcessTasks } from '@/services/approval';
import Avatar from '@/components/avatar';
import ContractSelectModal from '@/components/ContractSelectModal';
// import config from '@/config';
// import { CaretRightOutlined } from '@ant-design/icons';
// import OrgUserModal from '@/components/org-user-modal';

const { Step } = Steps;
const { Panel } = Accordion;
const config = {
  successCode: 200
};
export type ProcessValidator = () => ProcessValidateResult;

type StartUserSelectItem = {
  persons: string;
  taskDefKey: string;
};

export interface ProcessValidateResult {
  result?: boolean;
  message?: string;
  value?: StartUserSelectItem[];
}

interface IProps extends ConnectProps {
  historyTask: HistoryTask[];
  srvTime?: number;
  renderMode?: string;
  form?: any;
  formData?: any;
  query?: any;
  updateProcess?: number;
  fn?: any;
  // 流程重新提交的时候 需要这个参数
  procInstId?: string;
  // 提供方法给外面进行流程的校验
  setValidateMethod?: (mth?: ProcessValidator) => void;
}

type ApprovalerSelectedType = { [key: string]: { person: any } };

const ProcessSteps: FC<IProps> = (props) => {
  const [historyTask, setHistoryTask] = useState<HistoryTask[]>([]);
  const [activeKey, setActiveKey] = useState<string>('1');
  const { current } = useRef({ timer: null });
  const [userModal, setUserModal] = useState<string>('');
  const [approvalerSelected, setApprovalerSelected] = useState<
    ApprovalerSelectedType
  >({});
  const approvalerSelectedRef = useRef<ApprovalerSelectedType>();
  /**
   * prevApprovalerSelected 用于存储上一次渲染的approvalerSelected值
   * 使用原因：多次快速更新 approvalerSelected 时会使用最后一个值合并更新，导致前面的值会丢失，
   *   此时如果新的 approvalerSelected  值对上一次的 approvalerSelected 值有依赖的话，会因为上个值的丢失产生预期之外的错误，
   *   因此在这里使用 prevApprovalerSelected 做缓存，类似 setState 函数式写法中的 prevProps
   * 
   */
  let prevApprovalerSelected = useRef<ApprovalerSelectedType>().current;

  useEffect(() => {
    const setMethod = (mth?: ProcessValidator) => {
      if (props.setValidateMethod) {
        props.setValidateMethod(mth);
      }
    };
    setMethod(validateProcess);
    return () => {
      setMethod();
    };
  }, []);

  useEffect(() => {
    if (props.updateProcess !== undefined) {
      // 防抖
      if (current.timer) {
        clearTimeout(current.timer);
      }
      current.timer = setTimeout(() => {
        console.log('updateProcess listener');
        showSteps();
      }, 500);
    }
  }, [props.updateProcess]);

  const handleResult = (selected?: ApprovalerSelectedType) => {
    if (!selected) {
      return null;
    }
    const result: StartUserSelectItem[] = [];
    for (const key in selected) {
      // console.log(selected[key]);
      result.push({
        taskDefKey: key,
        persons: selected[key].person.map((item: any) => item.key).join(',')
      });
    }
    return result;
  };

  const validateProcess = () => {
    const tmp = approvalerSelectedRef.current || {};
    // if (!tmp || !Object.keys(tmp).length) {
    //   return { result: false, message: '请选择审批流程中的发起人自选节点' };
    // }
    for (const key in tmp) {
      if (!tmp[key].person || tmp[key].person.length === 0) {
        return { result: false, message: '发起人自选的节点至少选择一个人' };
      }
    }
    return {
      result: true,
      message: '',
      value: handleResult(approvalerSelectedRef.current)
    };
  };

  const showSteps = async () => {
    await props.form?.validateFields(
      (err: any) => {
        // 若果错误不为 null 收起下拉框
        if (err && err !== null) {
          setActiveKey('1');
        }
      },
      undefined,
      undefined,
      false,
    );
    onShowChange('0');
  };

  const renderReason = (useTask: UserTask) => {
    if (!useTask.handlerComment) {
      return null;
    }
    return <div className="longText">{useTask.handlerComment}</div>;
  };

  const renderProcess = (historyItem: HistoryTask) => {
    if (!historyItem.userTasks) return;
    const userTasks = historyItem.userTasks as TaskItem[];
    // console.log('是否发起人自选：', isStartUserChoose(historyItem.userTasks));
    return (
      <div>
        <h4 className={styles.processtitle}>{historyItem.taskName}</h4>
        {/* 如果是发起人自选则展示选择人员的组件 */}
        {
          isStartUserChoose(historyItem.userTasks)
            ? renderAddHandlers(historyItem)
            : renderProcessItem(userTasks)
        }
      </div>
    );
  };

  const hideUserModalStatus = () => {
    setUserModal('');
  };

  const showUserModalStatus = (key: string) => {
    setUserModal(key);
  };

  const submitHandlers = async (
    historyItemLocal: HistoryTask,
    checkedOrgs: string[]
  ) => {
    const taskDefKey = historyItemLocal.taskDefKey;
    const tmpApprovalerSelected = { ...approvalerSelected };
    if (!tmpApprovalerSelected[taskDefKey]) {
      tmpApprovalerSelected[taskDefKey] = {} as any;
    }
    tmpApprovalerSelected[taskDefKey].person = checkedOrgs;
    setStartUserSelected(tmpApprovalerSelected);
    hideUserModalStatus();
    // console.log('setStartUserSelected', tmpApprovalerSelected);
    // console.log('approvalerSelected', approvalerSelected);
  };

  // 发起人自选的情况 渲染选择人员组件
  const renderAddHandlers = (historyItemLocal: HistoryTask) => {
    let receiveData = [];
    if (props.choosePersons?.length) {
      receiveData = props.choosePersons
        .filter((item: any) => item.taskDefKey === historyItemLocal.taskDefKey)[0]?.persons // 选出对应自选节点的自选人
        ?.split(',')
        ?.map((item: any) => ({
          value: item,
          type: 2
        }));
    }
    const approvalerSelectedList = approvalerSelected[historyItemLocal.taskDefKey]?.person;
    const checkedIds = approvalerSelectedList?.length ? approvalerSelectedList : receiveData;
    return (
      <React.Fragment>
        <div className={styles.checkedMemberList}>
          {
            props.renderMode !== 'detail' &&
            <div className={styles.addMemberBtn} onClick={() => showUserModalStatus(historyItemLocal.taskDefKey)}>
              <i className="icon iconfont">&#xe70c;</i>
            </div>
          }
          {
            checkedIds?.map((item: any, index: number) => (
              <div className={styles.checkedMemberItem} key={item.key || index}>
                <Avatar name={item.title} />
              </div>
            ))
          }
        </div>
        <ContractSelectModal
          modalStatus={userModal === historyItemLocal.taskDefKey}
          closeModal={hideUserModalStatus}
          submit={(_isHandle, selectArray) => { submitHandlers(historyItemLocal, selectArray); }}
          type="person"
          receiveData={checkedIds}
          mode="multiple"
          orgData={props.orgTree || {}}
        />
      </React.Fragment>
    );
  };

  const renderProcessItem = (userTasks: TaskItem[]) => {
    return userTasks.map((taskItem, index) => {
      
      if (!taskItem.handlerName) return null;
      return (
        <div key={taskItem.taskRecordId || index} className={styles.step}>
          <div className={styles.useInfo}>
            {taskItem.noAvator != 1 && (
              <div className={styles.avator}>
                <Avatar name={taskItem?.handlerName} />
              </div>
            )}
            <span className={styles.handlerNameAndStatus}>
              {taskItem.handlerName}
              {taskItem.taskStatusName && taskItem.handlerName ? (
                <span className="dot-symbol"></span>
              ) : null}
              {taskItem.taskStatusName}
            </span>
          </div>
          <div className={styles.desc}>
            {renderReason(taskItem as UserTask)}
          </div>
        </div>
      );
    });
  };

  // 这里后端 如果是发起人自选的节点，会多返回一个节点，里面有个标示叫做startUserChoose
  const isUserTaskMockAdd = (userTaskItem: UserTask) => {
    return userTaskItem.startUserChoose === 1;
  };

  // 是否发起人自选的节点
  const isStartUserChoose = (userTaskLocal?: UserTask[]) => {
    return userTaskLocal?.some((el) => {
      return isUserTaskMockAdd(el); // 1为发起人自选
    });
  };

  // 从历史记录中 读取发起人自选的信息 进行初始化
  const getSelectedFromHistoryTask = (historyTaskLocal?: HistoryTask[]) => {
    if (!historyTaskLocal) return {};
    // console.log('historyTaskLocal', historyTaskLocal);
    const result: ApprovalerSelectedType = {};
    historyTaskLocal.forEach((historyTaskItem) => {
      if (
        historyTaskItem.taskDefKey &&
        isStartUserChoose(historyTaskItem.userTasks)
      ) {
        if (!result[historyTaskItem.taskDefKey]) {
          result[historyTaskItem.taskDefKey] = {} as any;
        }
        result[historyTaskItem.taskDefKey].person = historyTaskItem.userTasks
          .filter((el) => {
            return !isUserTaskMockAdd(el) && el.handler;
          })
          .map((el) => el.handler as string);
      }
    });
    return result;
  };

  const setStartUserSelected = (selected: ApprovalerSelectedType) => {
    setApprovalerSelected({
      ...prevApprovalerSelected,
      ...selected
    });
    prevApprovalerSelected = selected;
    approvalerSelectedRef.current = selected;
  };

  const onShowChange = async (
    key: string | string[] = '1'
    // isShowErrors = true
  ) => {
    const { query } = props;
    // 表单校验
    let pass = true;
    const values = await props.form?.validateFields().catch((err: any) => {
      if (err && err.errors) {
        // for (const k1 in props.formValues) {
        for (const key in err.errors) {
          // if (k1 == key) {
          const errMsg = err.errors[key]?.errors?.[0].message;
          pass = false;
          Toast.fail(errMsg);
          return;
          // }
        }
        // }
      }
    });
    if (!pass) return;
    console.log('key', key);
    console.log('values', values);
    console.log('formValues', props.formValues);

    // todo ?? 修复bug [修改表单，流程审批人清空了]   添加条件[&& historyTask?.length === 0]
    if (props.dispatch && key[0] == '0' && historyTask?.length === 0) {
      // console.log('values', values, props);
      const formValues = JSON.stringify(props.renderMode !== 'detail' ? values : props.formValues);
      const payload = {
        forms: {
          formModelData: props.formData,
          formValues
        },
        procInstId: query?.procInstId, // 重新提交才有
        innerProcDefId: query?.innerProcDefId
      };
      const res = await getProcessTasks(payload);
      if (res && res.status == config.successCode) {
        const historyTaskC: any = res.data || [];
        // 展示发起和结束
        historyTaskC.unshift({
          taskName: '发起',
          userTasks: [
            {
              noAvator: 1
            }
          ]
        });
        historyTaskC.push({
          taskName: '结束',
          userTasks: [
            {
              noAvator: 1
            }
          ]
        });
        setHistoryTask(historyTaskC);
        // 设置发起人自选的信息
        const tmpApprovalerSelected = getSelectedFromHistoryTask(historyTaskC);
        // 如果已选审批人，则复用已选的值
        console.log('设置approvalerSelected ', tmpApprovalerSelected);
        if (Object.keys(approvalerSelected)) {
          setStartUserSelected(approvalerSelected);
        } else {
          setStartUserSelected(tmpApprovalerSelected);
        }
      }
      // });
    }
    if (key[0] == '0') {
      // setIsShowText('收起');
      setActiveKey(key[0]);
      // 初始化一次表单变动 1：发生变化，0：未变化
      if (props.dispatch) {
        props.dispatch({
          type: 'capproval/formValuesChange',
          payload: {
            formStatus: key[0]
          }
        });
      }
    } else {
      // setIsShowText('展开');
      setActiveKey(key[0]);
    }
  };


  return (
    <Accordion
      accordion
      onChange={onShowChange}
      className={styles.collapseProcess}
      activeKey={activeKey}
    >
      <Panel header={'审批流程'} key="0">
        {
          historyTask.length > 0 &&
          <Steps current={-1} direction="vertical" size="small">
            {historyTask.map((historyItem, index) => (
              <Step
                key={historyItem.taskDefKey || index}
                title={renderProcess(historyItem)}
              />
            ))}
          </Steps>
        }
      </Panel>
    </Accordion>
  );
};

export default connect(({ capproval, loading, common }: ConnectState) => {
  return {
    orgTree: common.orgTree,
    updateProcess: capproval.updateProcess,
    treeLoading: loading.effects['design/getProcessTasks']
  };
})(ProcessSteps);
